---@class GT.unit
---@field unit_id UnitID|number 单位id
---@field unit Unit 单位
---@field key UnitKey 单位编号
---@field pos GT.point 位置
---@field angle Fixed 朝向
---@field player GT.player 所属玩家
---@field binding UnitKeyFloatAttr|binding_data 绑定值
---@field ability_data table<AbilityID,abilityInit_data> 技能数据[]
GT.unit = class()

---@class unit_data
---@field unit_id UnitID|number 单位id
---@field unit Unit 单位
---@field key UnitKey 单位编号
---@field pos GT.point 位置
---@field angle Fixed 朝向
---@field player GT.player 所属玩家

---@class binding_data
---@field pos GT.point 位置
---@field x number 位置
---@field y number 位置
---@field z number 位置
---@field shoot_fly shoot_fly_data 击飞

---@generic K
---@generic V
---@generic O
---@alias kv_call fun(K:K,V:V,old:O):void 自定义值修改回调



---@param data unit_data
function GT.unit:ctor(data)
    self.unit_id = data.unit_id
    self.unit = data.unit
    self.ability_data=OrderedTable()
    self.bind = new(bind, self)
    self.binding = self.bind.bindable

    for k, v in pairs(UnitKeyFloatAttr) do
        self[k] = self:api_get_float_attr(v)
        self.bind:add_({
            key = '=' .. k,
            func = function(val, old)
                if val == nil then
                    return
                end
                self[k] = val
                self:api_set_str_attr(v, self[k])
            end
        })
        self.bind:add_({
            key = k,
            func = function(val, old)
                if val == nil then
                    return
                end
                self[k] = val
                self:api_set_str_attr(v, self[k])
            end
        })
        self.bind:add_({
            key = '+' .. k,
            func = function(val, old)
                if val == nil then
                    return
                end

                self[k] = self[k] + val

                self:api_set_str_attr(v, self[k])
            end
        })
        self.bind:add_({
            key = '-' .. k,
            func = function(val, old)
                if val == nil then
                    return
                end
                self[k] = self[k] - val
                self:api_set_str_attr(v, self[k])
            end
        })
    end
    self:unit_watch()
    self['击飞'] = false
    self['眩晕'] = false
    self['击退'] = false
    self['禁止'] = false
end

---转对象
---@param unit Unit
---@return GT.unit
function GT.unit.obj(unit)
    if unit == nil then
        return nil
    end
    local obj = all_cache:get(tostring(unit))
    if obj == nil then
        obj = new(GT.unit, { unit = unit })
        all_cache:set(tostring(unit), obj)
    end
    return obj
end

---监听绑定
function GT.unit:unit_watch()
    self.bind:add({
        {
            key = "pos",
            func = function(val, old)
                self.pos = val
                self:blink(val)
            end
        },
        {
            key = "x",
            func = function(val, old)
                self.x = val
                local p = self:api_get_position()
                self:blink(GT.point.vec3(val, p.y, p.z))
            end
        },
        {
            key = "y",
            func = function(val, old)
                self.y = val
                local p = self:api_get_position()
                self:blink(GT.point.vec3(p.x, val, p.z))
            end
        },
        {
            key = "z",
            func = function(val, old)
                self.z = val
                self:api_raise_height(val, 0)
            end
        },
        -- {
        --     key = "shoot_fly",
        --     func = function(val, old)
        --         if val == nil then
        --             return
        --         end
        --         self:shoot_fly(val)
        --     end
        -- },


    })
end

function GT.unit:update_pos()
    local p = self:api_get_position()
    self.x = p:get_point_x()
    self.y = p:get_point_y()
    self.z = self:api_get_height()
end

function GT.unit:__tostring()
    return tostring(self.unit)
end

---@param point GT.point 点
---移动到点（瞬间）
function GT.unit:blink(point)
    self.unit.api_transmit(point.point)
end

---@param point GT.point 点
---@param isSmooth boolean 是否丝滑
---强制移动
function GT.unit:set_point(point, isSmooth)
    self.unit.api_force_transmit_new(point.point, isSmooth)
end

---创建单位
---@param key UnitKey 单位编号
---@param pos GT.point 位置
---@param angle Fixed 朝向
---@param player GT.player 所属玩家
---@return GT.unit
function GT.unit.create_unit(key, pos, angle, player)
    return GT.unit.obj(game_api.create_unit(key, pos.point, angle, player.player))
end

---创建单位-在单位脚底创建单位
---@param key UnitKey 单位编号
---@param u GT.unit 单位
---@param attr table<uKeyAttr,number> 单位属性
---@return GT.unit
function GT.unit:create_unit_foot(key, attr)
    local u = GT.unit.create_unit(key, self:api_get_position(), 0, self:get_player())
    if attr ~= nil then
        for k, v in pairs(attr) do
            u.binding[k] = v
            local key = string.gsub(k, "-", "")
            key = string.gsub(key, "+", "")
            if key == uKeyAttr['最大生命值'] then
                u.binding[uKeyAttr['当前生命值']] = u[uKeyAttr['最大生命值']]
            end
            if key == uKeyAttr['最大法力值'] then
                u.binding[uKeyAttr['当前法力值']] = u[uKeyAttr['当前法力值']]
            end
        end
    end
    return u
end

---添加集合技能
---@param skills any
function GT.unit:add_skills(skills)
    if skills ~= nil then
        for index, value in ipairs(skills) do
            self:add_ability_index(value)
        end
    end
end

--- 创建幻象
---@param clone_unit GT.unit 复制目标
---@param caller_unit GT.unit 召唤者
---@param role GT.player 玩家
---@param pos GT.point 位置
---@param angle Fixed 朝向
---@return GT.unit
function GT.unit.create_illusion(clone_unit, caller_unit, role, pos, angle)
    return GT.unit.obj(game_api.create_illusion(clone_unit.unit, caller_unit.unit, role.player, pos.point, angle))
end

--- 获取幻象召唤者
---@param illusion_unit GT.unit 幻象单位
---@return GT.unit
function GT.unit.get_illusion_caller_unit(illusion_unit)
    return GT.unit.obj(game_api.get_illusion_caller_unit(illusion_unit.unit))
end

--- 获取幻象召唤者
---@return Unit
function GT.unit:get_illusion_caller_unit()
    return self.unit.get_illusion_caller_unit(self.unit)
end

--- 判断单位是否是幻象单位
---@param unit Unit 单位
---@return Bool
function GT.unit:is_unit_illusion()
    game_api.is_unit_illusion(self.unit)
end

--- 改变单位所属玩家
---@param role Role 所属玩家
function GT.unit:change_unit_role(role)
    game_api.change_unit_role(self.unit, role)
end

--- 移除玩家控制列表中的单位
---@param role Role 玩家
function GT.unit:remove_control_unit(role)
    game_api.change_unit_role(self.unit, role)
end

--- 给队伍添加单位
---@param role Role 玩家
---@param team_id Int32 队伍编号
function GT.unit:add_unit_to_team(role, team_id)
    game_api.add_unit_to_team(role, team_id, self.unit)
end

--- 从队伍中去除单位
---@param role Role 玩家
---@param team_id Int32 队伍编号
function GT.unit:remove_unit_from_team(role, team_id)
    game_api.remove_unit_from_team(role, team_id, self.unit)
end

--- 判断单位是否在单位组
---@param group UnitGroup 单位组
---@return Bool
function GT.unit:unit_in_group(group)
    return game_api.judge_unit_in_group(group)
end

--- 获取单位ID
---@return UnitID
function GT.unit:api_get_id()
    return self.unit.api_get_id()
end

--- 根据单位ID获取单位
---@param unit_id UnitID 单位id
---@return GT.unit
function GT.unit.get_unit_by_id(unit_id) return GT.unit.obj(game_api.get_unit_by_id(unit_id)) end

--- 单位移除键值对
---@param k Str 键名
function GT.unit:api_remove_kv(k) self.unit.api_remove_kv(k) end

--- 单位是否存活
---@return Bool
function GT.unit:api_is_alive() return self.unit.api_is_alive() end

--- 隐藏头顶信息
---@param show Bool 是否隐藏头顶信息
function GT.unit:api_hide_head_bar(show) self.unit.api_hide_head_bar(show) end

--- 单位是否拥有标签
---@param tag Str 标签
---@return Bool
function GT.unit:has_tag(tag) return self.unit.has_tag(tag) end

--- 复活单位
---@param position Point 复活位置
function GT.unit:api_revive(position)
    self.unit.api_revive(position)
end

--- 单位是否已销毁
---@return Bool
function GT.unit:api_is_destroyed()
    return self.unit.api_is_destroyed()
end

--- 删除单位
function GT.unit:api_delete()
    self.unit.api_delete()
    all_cache:del(tostring(self.unit))
end

--- 强制单位死亡
---@param source_unit Unit 杀手单位
function GT.unit:api_kill(source_unit)
    self.unit.api_kill(source_unit)
end

--- 获取单位图标路径
---@return Str
function GT.unit:api_get_icon()
    return self.unit.api_get_icon()
end

--- 获取单位图片路径
---@param pic_type Str 图片类型
---@return Str
function GT.unit:api_get_unit_pic(pic_type)
    return self.unit.api_get_unit_pic(pic_type)
end

--- 获取单位的父单位
---@return Unit
function GT.unit:api_get_parent_unit()
    return self.unit.api_get_parent_unit()
end

--- 改变单位血条颜色
---@param color Str 单位血条颜色值
function GT.unit:api_set_hp_color(color)
    self.unit.api_set_hp_color(color)
end

--- 开启/关闭伤害及助攻统计
---@param enable Bool 开启
function GT.unit:api_switch_atk_assist_record(enable)
    self.unit.api_switch_atk_assist_record(enable)
end

--- 单位/点是否在范围内
---@param unit Unit 单位
---@param radius Float 范围
---@return Bool
function GT.unit:api_is_in_range(unit, radius)
    return self.unit.api_is_in_range(unit, radius)
end

--- 点是否在范围内
---@param point Point 点
---@param radius Float 范围
---@return Bool
function GT.unit:api_is_point_in_range(point, radius)
    return self.unit.api_is_point_in_range(point, radius)
end

--- 设置单位生命周期
---@param life_time Float 生命周期
function GT.unit:api_set_life_cycle(life_time)
    self.unit.api_set_life_cycle(life_time)
end

--- 暂停单位生命周期
---@param pause Bool 是否暂停
function GT.unit:api_pause_life_cycle(pause)
    self.unit.api_pause_life_cycle(pause)
end

--- 获取单位当前生命周期
---@return Fixed
function GT.unit:api_get_life_cycle()
    return self.unit.api_get_life_cycle()
end

--- 获取单位总生命周期时长
---@return Fixed
function GT.unit:api_get_total_life_cycle()
    return self.unit.api_get_total_life_cycle()
end

--- 设置单位攻击类型
---@param attack_type UInt32 攻击类型
function GT.unit:api_set_attack_type(attack_type)
    self.unit.api_set_attack_type(attack_type)
end

--- 获取单位攻击类型
---@return UInt32
function GT.unit:api_get_atk_type()
    return self.unit.api_get_atk_type()
end

--- 攻击类型判断
---@param attack_type UInt32 攻击类型
---@return Bool
function GT.unit:api_is_attack_type(attack_type)
    return self.unit.api_is_attack_type(attack_type)
end

--- 设置单位护甲类型
---@param armor_type UInt32 护甲类型
function GT.unit:api_set_armor_type(armor_type)
    self.unit.api_set_armor_type(armor_type)
end

--- 获取单位护甲类型
---@return UInt32
function GT.unit:api_get_armor_type()
    return self.unit.api_get_armor_type()
end

--- 护甲类型判断
---@param armor_type UInt32 护甲类型
---@return Bool
function GT.unit:api_is_armor_type(armor_type)
    return self.unit.api_is_armor_type(armor_type)
end

--- 获取单位的x轴缩放
---@return Float
function GT.unit:api_get_x_scale()
    return self.unit.api_get_x_scale()
end

--- 获取单位的y轴缩放
---@return Float
function GT.unit:api_get_y_scale()
    return self.unit.api_get_y_scale()
end

--- 获取单位的z轴缩放
---@return Float
function GT.unit:api_get_z_scale()
    return self.unit.api_get_z_scale()
end

--- 获取单位属性(额外属性)
---@param key UnitKeyFloatAttr 属性名
---@return Fixed
function GT.unit:api_get_attr_other(key)
    return self.unit.api_get_attr_other(key)
end

--- 获取单位属性(基础属性)
---@param key UnitKeyFloatAttr 属性名
---@return Fixed
function GT.unit:api_get_attr_base(key)
    return self.unit.api_get_attr_base(key)
end

--- 获取attr_base_ratio
---@param key UnitKeyFloatAttr 属性名
---@return Fixed
function GT.unit:api_get_attr_base_ratio(key)
    return self.unit.api_get_attr_base_ratio(key)
end

--- 获取attr_bonus
---@param key UnitKeyFloatAttr 属性名
---@return Fixed
function GT.unit:api_get_attr_bonus(key)
    return self.unit.api_get_attr_bonus(key)
end

--- 获取attr_bonus_ratio
---@param key UnitKeyFloatAttr 属性名
---@return Fixed
function GT.unit:api_get_attr_bonus_ratio(key)
    return self.unit.api_get_attr_bonus_ratio(key)
end

--- 获取attr_all_ratio
---@param key UnitKeyFloatAttr 属性名
---@return Fixed
function GT.unit:api_get_attr_all_ratio(key)
    return self.unit.api_get_attr_all_ratio(key)
end

--- 获取单位主属性
---@return Str
function GT.unit:api_get_main_attr()
    return self.unit.api_get_main_attr()
end

--- 设置纯值类型的值
---@param key Str 属性名
---@param val Fixed 值
function GT.unit:api_set_attr(key, val)
    self.unit.api_set_attr(key, val)
end

--- 设置单位属性（根据属性分类）
---@param key Str 属性名
---@param val Fixed 值
---@param attr_element Str 属性分类
function GT.unit:api_set_attr_by_attr_element(key, val, attr_element)
    self.unit.api_set_attr_by_attr_element(key, val, attr_element)
end

--- 设置单位属性基础值部分
---@param key Str 属性名
---@param val Fixed 基础值
function GT.unit:api_set_attr_base(key, val)
    self.unit.api_set_attr_base(key, val)
end

--- 增加单位属性（根据属性分类）
---@param key Str 属性名
---@param val Fixed 值
---@param attr_element Str 属性分类
function GT.unit:api_add_attr_by_attr_element(key, val, attr_element)
    self.unit.api_add_attr_by_attr_element(key, val, attr_element)
end

--- 增加单位属性基础值
---@param key Str 属性名
---@param delta Fixed 增加值
function GT.unit:api_add_attr_base(key, delta)
    self.unit.api_add_attr_base(key, delta)
end

--- 设置单位属性 attr_bonus
---@param key Str 属性名
---@param val Fixed 设置值
function GT.unit:api_set_attr_bonus(key, val)
    self.unit.api_set_attr_bonus(key, val)
end

--- 增加单位属性 attr_bonus
---@param key Str 属性名
---@param delta Fixed 增加值
function GT.unit:api_add_attr_bonus(key, delta)
    self.unit.api_add_attr_bonus(key, delta)
end

--- 设置单位属性 attr_bouns_ratio
---@param key Str 属性名
---@param val Fixed 设置值
function GT.unit:api_set_attr_bonus_ratio(key, val)
    self.unit.api_set_attr_bonus_ratio(key, val)
end

--- 增加单位属性 attr_bouns_ratio
---@param key Str 属性名
---@param delta Fixed 加成比例
function GT.unit:api_add_attr_bonus_ratio(key, delta)
    self.unit.api_add_attr_bonus_ratio(key, delta)
end

--- 设置单位属性 基础值和额外值 加成比例
---@param key Str 属性名
---@param val Fixed 设置值
function GT.unit:api_set_attr_all_ratio(key, val)
    self.unit.api_set_attr_all_ratio(key, val)
end

--- 增加单位属性 基础值和额外值 加成比例
---@param key Str 属性名
---@param delta Fixed 加成比例
function GT.unit:api_add_attr_all_ratio(key, delta)
    self.unit.api_add_attr_all_ratio(key, delta)
end

--- 设置单位属性 基础值 加成比例
---@param key Str 属性名
---@param val Fixed 设置值
function GT.unit:api_set_attr_base_ratio(key, val)
    self.unit.api_set_attr_base_ratio(key, val)
end

--- 增加单位属性基础值百分比加成
---@param key Str 属性名
---@param delta Fixed 加成比例
function GT.unit:api_add_attr_base_ratio(key, delta)
    self.unit.api_add_attr_base_ratio(key, delta)
end

--- 设置单位等级
---@param level Int32 等级
function GT.unit:api_set_level(level)
    self.unit.api_set_level(level)
end

--- 增加单位等级
---@param level Int32 等级
function GT.unit:api_add_level(level)
    self.unit.api_add_level(level)
end

--- 获取单位实数属性(实际属性)
---@param attr UnitKeyFloatAttr 属性名
---@return Fixed
function GT.unit:api_get_float_attr(attr)
    return self.unit.api_get_float_attr(attr):float()
end

--- 获取单位字符串属性(实际属性)
---@param attr UnitKeyFloatAttr 属性名
---@return Str
function GT.unit:api_get_str_attr(attr)
    return self.unit.api_get_str_attr(attr)
end

--- 设置单位字符串属性
---@param attr UnitKeyFloatAttr 属性名
---@param value Str 字符串值
function GT.unit:api_set_str_attr(attr, value)
    self.unit.api_set_str_attr(attr, value)
end

--- 获取单位等级
---@return UInt32
function GT.unit:api_get_level()
    return self.unit.api_get_level()
end

--- 获取单位血量
---@return Fixed
function GT.unit:api_get_hp()
    return self.unit.api_get_hp()
end

--- 获取单位血量百分比
---@return Fixed
function GT.unit:api_get_hpp()
    return self.unit.api_get_hpp()
end

--- 获取输出伤害统计值
---@return Fixed
function GT.unit:api_get_dmg_statistics()
    return self.unit.api_get_dmg_statistics()
end

--- 清空输出伤害统计值
function GT.unit:api_clear_dmg_statistics()
    self.unit.api_clear_dmg_statistics()
end

--- 增加经验，增加值为正数
---@param exp Fixed 经验
function GT.unit:api_add_exp(exp)
    self.unit.api_add_exp(exp)
end

--- 设置经验
---@param exp Fixed 经验
function GT.unit:api_set_exp(exp)
    self.unit.api_set_exp(exp)
end

--- 获取单位当前经验, 如果达到了顶级，就返回-1
---@return UInt32
function GT.unit:api_get_exp()
    return self.unit.api_get_exp() or 0
end

--- 获取当前升级所需经验, 如果达到了顶级，就返回-1
---@return Fixed
function GT.unit:api_get_upgrade_exp()
    return self.unit.api_get_upgrade_exp() or 0
end

--- 单位移除键值对
---@param tag Str TAG
function GT.unit:api_add_tag(tag)
    self.unit.api_add_tag(tag)
end

--- 单位移除键值对
---@param tag Str TAG
function GT.unit:api_remove_tag(tag)
    self.unit.api_remove_tag(tag)
end

--- 设置单位删除时是否回收
---@param recycle Bool 是否回收
function GT.unit:api_set_recycle_on_remove(recycle)
    self.unit.api_set_recycle_on_remove(recycle)
end

--- 设置单位名称
---@param name Str 名称
function GT.unit:api_set_name(name)
    self.unit.api_set_name(name)
end

--- 设置单位白天视野
---@param value Float 视野
function GT.unit:api_set_unit_day_vision(value)
    self.unit.api_set_unit_day_vision(value)
end

--- 获取单位白天视野
---@return Fixed
function GT.unit:api_get_unit_day_vision()
    return self.unit.api_get_unit_day_vision()
end

--- 设置单位夜晚视野
---@param value Float 视野
function GT.unit:api_set_unit_night_vision(value)
    self.unit.api_set_unit_night_vision(value)
end

--- 获取单位夜晚视野
---@return Fixed
function GT.unit:api_get_unit_night_vision()
    self.unit.api_get_unit_night_vision()
end

--- 设置单位警戒范围
---@param value Float 警戒范围
function GT.unit:api_set_unit_alarm_range(value)
    self.unit.api_set_unit_alarm_range(value)
end

--- 获取单位警戒范围
---@return Fixed
function GT.unit:api_get_unit_alarm_range()
    return self.unit.api_get_unit_alarm_range()
end

--- 设置单位取消警戒范围
---@param value Float 取消警戒范围
function GT.unit:api_set_unit_cancel_alarm_range(value)
    self.unit.api_set_unit_cancel_alarm_range(value)
end

--- 获取单位取消警戒范围
---@return Fixed
function GT.unit:api_get_unit_cancel_alarm_range()
    return self.unit.api_get_unit_cancel_alarm_range()
end

--- 获取单位物品栏数量
---@return UInt64
function GT.unit:api_get_unit_bar_cnt()
    self.unit.api_get_unit_bar_cnt()
end

--- 获取单位背包栏数量
---@return UInt64
function GT.unit:api_get_unit_pkg_cnt()
    return self.unit.api_get_unit_pkg_cnt()
end

--- 获取单位动态碰撞半径
---@return Fixed
function GT.unit:api_get_unit_collision_radius()
    return self.unit.api_get_unit_collision_radius()
end

--- 获取单位被击杀经验
---@return Int32
function GT.unit:api_get_unit_reward_exp()
    return self.unit.api_get_unit_reward_exp()
end

--- 获取单位被击杀的玩家属性
---@param res_key Fixed 经验值
function GT.unit:api_get_unit_reward_res(res_key)
    self.unit.api_get_unit_reward_res(res_key)
end

--- 设置单位被击杀经验
---@param res_value Fixed 经验值
function GT.unit:api_set_unit_reward_exp(res_value)
    self.unit.api_set_unit_reward_exp(res_value)
end

--- 设置单位被击杀的玩家属性
---@param res_key RoleResKey 玩家属性资源
---@param res_value Fixed 经验值
function GT.unit:api_set_unit_reward_res(res_key, res_value)
    self.unit.api_set_unit_reward_res(res_key, res_value)
end

--- 获取单位的护盾值
---@param shield_type Int32 护盾值
function GT.unit:api_get_unit_shield_value(shield_type)
    self.unit.api_get_unit_shield_value(shield_type)
end

--- 设置单位的头像
---@param icon Texture 图片
function GT.unit:api_set_unit_icon(icon)
    self.unit.api_set_unit_icon(icon)
end

--- 单位停止移动
function GT.unit:api_stop_move()
    self.unit.api_stop_move()
end

--- 单位传送到指定坐标
---@param point FVector3 目标坐标
function GT.unit:api_transmit(point)
    self.unit.api_transmit(point)
end

--- 单位强制传送到指定坐标
---@param pos FVector3 目标坐标
function GT.unit:api_force_transmit(pos)
    self.unit.api_force_transmit(pos)
end

--- 单位强制传送到指定坐标
---@param pos FVector3 目标坐标
---@param interpolation Bool 是否平滑
function GT.unit:api_force_transmit_new(pos, interpolation)
    self.unit.api_force_transmit_new(pos, interpolation)
end

--- 单位设置朝向
---@param face_dir FVector3 朝向
---@param speed_effect Bool 是否受转身速度影响
function GT.unit:api_set_face_dir(face_dir, speed_effect)
    self.unit.api_set_face_dir(face_dir, speed_effect)
end

--- 单位设置朝向角度
---@param face_angle Fixed 朝向角度
---@param turn_time_ms Int32 转身时间毫秒
function GT.unit:api_set_face_angle(face_angle, turn_time_ms)
    self.unit.api_set_face_angle(face_angle, turn_time_ms)
end

--- 单位是否能传送到目标点
---@param pos FVector3 目标点
---@return Bool
function GT.unit:api_can_teleport_to(pos)
    return self.unit.api_can_teleport_to(pos)
end

--- 获取单位在目标点附近的最近可通行点
---@return FVector3
function GT.unit:api_find_nearest_valid_position()
    return self.unit.api_find_nearest_valid_position()
end

--- 获取单位位置
---@return GT.point
function GT.unit:api_get_position()
    return GT.point.obj(self.unit.api_get_position())
end

--- 获取单位朝向
---@return FVector3
function GT.unit:api_get_face_dir()
    return self.unit.api_get_face_dir()
end

--- 获取单位面向角度
---@return Fixed
function GT.unit:api_get_face_angle()
    return self.unit.get_face_angle():float()
end

--- 设置单位转身速度
---@param turn_speed Fixed 转身速度
function GT.unit:api_set_turn_speed(turn_speed)
    return self.unit.api_set_turn_speed(turn_speed)
end

--- 获得单位转身速度
---@return Fixed
function GT.unit:api_get_turn_speed()
    return self.unit.api_get_turn_speed()
end

--- 单位是否在移动
---@return Bool
function GT.unit:api_is_moving()
    return self.unit.api_is_moving()
end

--- 设置单位是否计算某种碰撞类型
---@param collision_layer Int32 碰撞mask
---@param enable Bool 开启状态
function GT.unit:api_set_move_collision(collision_layer, enable)
    self.unit.api_set_move_collision(collision_layer, enable)
end

--- 获取单位是否计算某种碰撞类型
---@param collision_layer Int32 碰撞mask
---@return Bool
function GT.unit:api_get_move_collision(collision_layer)
    return self.unit.api_get_move_collision(collision_layer)
end

--- 播放动画
---@param name Str 动画名称
---@param rate Float 播放倍率
---@param init_time Float 开始时间(s)
---@param end_time Float 结束时间(s)，正数 -1 表示不结束
---@param loop Bool 是否循环
---@param return_idle Bool 播放结束后是否恢复idle
function GT.unit:api_play_animation(name, rate, init_time, end_time, loop, return_idle)
    self.unit.api_play_animation(name, rate, init_time, end_time, loop, return_idle)
end

--- 停止播放动画
---@param name Str 动画名称
function GT.unit:api_stop_animation(name)
    self.unit.api_stop_animation(name)
end

--- 停止当前正在播放的动画
function GT.unit:api_stop_cur_animation()
    self.unit.api_stop_cur_animation()
end

--- 设置动画速度
---@param speed Fixed 速度
function GT.unit:api_set_animation_speed(speed)
    self.unit.api_set_animation_speed(speed)
end

--- 单位播放特效
---@param socket_name Str 挂节点名字
---@param sfx_res_id SfxKey 特效编号
---@param keep_time Fixed 持续时间，单位：秒
---@param scale Float 缩放比例
---@param inherit_pos Bool 是否跟随单位位置
---@param inherit_rotate Bool 是否跟随单位旋转
---@param inherit_scale Bool 是否跟随缩放
---@param role Role 所属单位
---@param visible_type SfxVisibleType 可见性规则
---@param rotation Float 初始旋转 角度制
function GT.unit:api_play_sfx(socket_name, sfx_res_id, keep_time, scale, inherit_pos, inherit_rotate, inherit_scale, role,
                              visible_type, rotation)
    self.unit.api_play_sfx(socket_name, sfx_res_id, keep_time, scale, inherit_pos, inherit_rotate, inherit_scale, role,
        visible_type, rotation)
end

--- 在单位挂接点播放特效
---@param socket_name Str 挂节点名字
---@param sfx_id SfxKey 特效编号
---@param keep_time Fixed 持续时间，单位：秒
---@param scale Float 缩放比例
---@param inherit_rotate Bool 是否跟随单位旋转
---@param inherit_scale Bool 是否跟随缩放
---@param role Role 所属玩家
---@param visible_type SfxVisibleType 可见性规则
function GT.unit:api_unit_play_sfx_on_socket(socket_name, sfx_id, keep_time, scale, inherit_rotate, inherit_scale, role,
                                             visible_type)
    self.unit.api_unit_play_sfx_on_socket(socket_name, sfx_id, keep_time, scale, inherit_rotate, inherit_scale, role,
        visible_type)
end

--- 在单位上播放特效并返回特效实体
---@param socket_name Str 挂节点名字
---@param sfx_res_id SfxKey 特效编号
---@param keep_time Fixed 持续时间，单位：秒
---@param scale Float 缩放比例
---@param inherit_pos Bool 是否跟随单位位置
---@param inherit_rotate Bool 是否跟随单位旋转
---@param inherit_scale Bool 是否跟随缩放
---@param role Role 所属单位
---@param visible_type SfxVisibleType 可见性规则
---@param rotation Float 初始旋转 角度制
---@return Sfx
function GT.unit:api_play_sfx_with_return(socket_name, sfx_res_id, keep_time, scale, inherit_pos, inherit_rotate,
                                          inherit_scale, role, visible_type, rotation)
    return self.unit.api_play_sfx_with_return(socket_name, sfx_res_id, keep_time, scale, inherit_pos, inherit_rotate,
        inherit_scale, role, visible_type, rotation)
end

--- 单位替换播放动画
---@param target_ani Str 目标动画名字
---@param source_ani Str 原动画名字
function GT.unit:api_change_animation(target_ani, source_ani)
    self.unit.api_change_animation(target_ani, source_ani)
end

--- 取消单位替换播放动画
---@param target_ani Str 目标动画名字
---@param source_ani Str 原动画名字
function GT.unit:api_cancel_change_animation(target_ani, source_ani)
    self.unit.api_cancel_change_animation(target_ani, source_ani)
end

--- 取消单位所有替换播放动画
---@param source_ani Str 原动画名字
function GT.unit:api_clear_change_animation(source_ani)
    self.unit.api_clear_change_animation(source_ani)
end

--- 单位替换模型
---@param target_model ModelKey 目标模型编号
---@param source_model ModelKey 原模型编号
function GT.unit:api_change_model(target_model, source_model)
    self.unit.api_change_model(target_model, source_model)
end

--- 取消单位替换模型
---@param target_model ModelKey 目标模型编号
---@param source_model ModelKey 原模型编号
function GT.unit:api_cancel_change_model(target_model, source_model)
    self.unit.api_cancel_change_model(target_model, source_model)
end

--- 取消单位所有替换模型
---@param source_model ModelKey 原模型编号
function GT.unit:api_clear_change_model(source_model)
    self.unit.api_clear_change_model(source_model)
end

--- 单位替换模型
---@param target_model ModelKey 目标模型编号
function GT.unit:api_replace_model(target_model)
    self.unit.api_replace_model(target_model)
end

--- 取消单位替换模型
---@param target_model ModelKey 目标模型名字
function GT.unit:api_cancel_replace_model(target_model)
    self.unit.api_cancel_replace_model(target_model)
end

--- 显示血条倒计时
---@param left_time Fixed 倒计时时长, 单位秒
function GT.unit:api_show_health_bar_count_down(left_time)
    self.unit.api_show_health_bar_count_down(left_time)
end

--- 获取单位模型
---@return ModelKey
function GT.unit:model()
    return self.unit.api_get_model()
end

--- 获取单位原模型
---@return ModelKey
function GT.unit:api_get_source_model()
    return self.unit.api_get_source_model()
end

--- 显示单位头顶文本
---@param text Str 显示信息
---@param second Fixed 持续时间, 单位秒
---@param localize Int32 多语言环境
function GT.unit:api_show_text(text, second, localize)
    self.unit.api_show_text(text, second, localize)
end

--- 更改单位称号
---@param title_str Str 称号
---@param localize Bool 多语言转化
function GT.unit:api_set_title(title_str, localize)
    self.unit.api_set_title(title_str, localize)
end

--- 设置单位称号可见性
---@param visible Bool 是否显示
function GT.unit:api_set_title_visible(visible)
    self.unit.api_set_title_visible(visible)
end

--- 隐藏显示单位名称,对于无头顶UI的单位该API不生效,每次隐藏计数+1,每次显示计数-1,计数归零显示单位名称
---@param visible Bool 是否显示
function GT.unit:api_set_name_visible(visible)
    self.unit.api_set_name_visible(visible)
end

--- 隐藏显示单位名称,对于无头顶UI的单位该API不生效,每次隐藏计数+1,每次显示计数-1,计数归零显示单位名称
---@param visible Bool 是否显示
function GT.unit:api_set_bar_name_visible(visible)
    self.unit.api_set_bar_name_visible(visible)
end

--- 设置血条显示名字
---@param name Str 名字
function GT.unit:api_set_bar_name(name)
    self.unit.api_set_bar_name(name)
end

--- 设置血条显示名字缩放
---@param scale Float 缩放
function GT.unit:set_bar_name_scale(scale)
    self.unit.set_bar_name_scale(scale)
end

--- 设置血条显示名字字体
---@param font_name Str 字体名称
function GT.unit:api_set_bar_name_font_type(font_name)
    self.unit.api_set_bar_name_font_type(font_name)
end

--- 设置血条显示名字字体大小
---@param size UInt32 字号
function GT.unit:api_set_bar_name_font_size(size)
    self.unit.api_set_bar_name_font_size(size)
end

--- 隐藏显示单位头顶文本,每次隐藏计数+1,每次显示计数-1,计数归零显示单位头顶文本
---@param visible Bool 是否显示
function GT.unit:api_set_bar_text_visible(visible)
    self.unit.api_set_bar_text_visible(visible)
end

--- 设置头顶显示文字缩放
---@param scale Float 缩放
function GT.unit:api_set_bar_text_scale(scale)
    self.unit.api_set_bar_text_scale(scale)
end

--- 设置头顶显示文字类型
---@param bar_text_type UInt32 类型
function GT.unit:api_set_bar_text_type(bar_text_type)
    self.unit.api_set_bar_text_type(bar_text_type)
end

--- 设置头顶显示文字字体
---@param font_type Str 字体
function GT.unit:api_set_bar_text_font_type(font_type)
    self.unit.api_set_bar_text_font_type(font_type)
end

--- 设置头顶显示文字字号
---@param font_size UInt32 字号
function GT.unit:api_set_bar_text_font_size(font_size)
    self.unit.api_set_bar_text_font_size(font_size)
end

--- 设置血条名称显示样式
---@param t UInt32 样式,具体参见**HeadBarShowNameType**
function GT.unit:api_set_bar_name_show_type(t)
    self.unit.api_set_bar_name_show_type(t)
end

--- 隐藏显示单位血条,对于无头顶UI的单位该API不生效,每次隐藏计数+1,每次显示计数-1,计数归零显示单位血条
---@param visible Bool 是否显示
function GT.unit:api_set_hp_bar_visible(visible)
    self.unit.api_set_hp_bar_visible(visible)
end

--- 设置单位血条显示样式,对于无头顶UI的单位该API不生效
---@param t UInt32 显示样式,具体参见**HeadBarShowType**
function GT.unit:api_set_hp_bar_show_type(t)
    self.unit.api_set_hp_bar_show_type(t)
end

--- 设置单位血条样式,对于无头顶UI的单位该API不生效
---@param t UInt32 血条样式
function GT.unit:api_set_hp_bar_type(t)
    self.unit.api_set_hp_bar_type(t)
end

--- 绑定UI控件
---@param ui_comp WorldUINode UI控件
---@param socket_name Str 挂接点(需确认模型拥有该挂接点,挂接点可在模型属性中查看,具体挂接点类型参见**ModelSocket**)
function GT.unit:api_add_ui_comp(ui_comp, socket_name)
    self.unit.api_add_ui_comp(ui_comp, socket_name)
end

--- 修改单位称号字号
---@param font_size UInt32 字号
function GT.unit:api_change_title_font_size(font_size)
    self.unit.api_change_title_font_size(font_size)
end

--- 修改单位称号缩放
---@param scale Float 缩放比例
function GT.unit:api_change_title_scale(scale)
    self.unit.api_change_title_scale(scale)
end

--- 修改单位称号字体
---@param font_name Str 字体
function GT.unit:api_change_title_font_type(font_name)
    self.unit.api_change_title_font_type(font_name)
end

--- 修改单位称号样式
---@param style_type UInt32 称号样式
function GT.unit:api_change_title_type(style_type)
    self.unit.api_change_title_type(style_type)
end

--- 修改单位称号背景不透明度
---@param opacity Float 不透明度
function GT.unit:api_set_title_bg_opacity(opacity)
    self.unit.api_set_title_bg_opacity(opacity)
end

--- 修改单位称号背景缩放
---@param scale Float 缩放
function GT.unit:api_set_title_bg_scale(scale)
    self.unit.api_set_title_bg_scale(scale)
end

--- 修改单位血条刻度可见性
---@param visible Bool 可见性
function GT.unit:api_set_blood_scale_visible(visible)
    self.unit.api_set_blood_scale_visible(visible)
end

--- 修改单位称号位置偏移
---@param offset Vector2 位置偏移
function GT.unit:api_set_title_bar_pos_offset(offset)
    self.unit.api_set_title_bar_pos_offset(offset)
end

--- 修改单位血条位置偏移
---@param offset Vector2 位置偏移
function GT.unit:api_set_hp_bar_pos_offset(offset)
    self.unit.api_set_hp_bar_pos_offset(offset)
end

--- 修改单位名称位置偏移
---@param offset Vector2 位置偏移
function GT.unit:api_set_name_bar_pos_offset(offset)
    self.unit.api_set_name_bar_pos_offset(offset)
end

--- 修改单位文本位置偏移
---@param offset Vector2 位置偏移
function GT.unit:api_set_text_bar_pos_offset(offset)
    self.unit.api_set_text_bar_pos_offset(offset)
end

--- 修改单位倒计时位置偏移
---@param offset Vector2 位置偏移
function GT.unit:api_set_countdown_bar_pos_offset(offset)
    self.unit.api_set_countdown_bar_pos_offset(offset)
end

--- 单位抬高
---@param y Fixed 抬高高度
---@param dt Fixed 时间
function GT.unit:api_raise_height(y, dt)
    self.unit.api_raise_height(Fix32(y), Fix32(dt))
end

--- 获取单位高度
---@return Fixed
function GT.unit:api_get_height()
    return self.unit.api_get_height():int()
end

--- 设置单位缩放
---@param scale Float 缩放
function GT.unit:api_set_scale(scale)
    self.unit.api_set_scale(scale)
end

--- 获取单位缩放
---@return Fixed
function GT.unit:api_get_scale()
    return self.unit.api_get_scale()
end

--- 获取单位模型缩放
---@return Fixed
function GT.unit:api_get_model_scale()
    return self.unit.api_get_model_scale()
end

--- 修改单位血条样式
---@param blood_bar_type UInt64 血条样式
function GT.unit:api_set_blood_bar_type(blood_bar_type)
    self.unit.api_set_blood_bar_type(blood_bar_type)
end

--- 修改单位血条显示模式
---@param blood_bar_show_type UInt64 血条显示模式
function GT.unit:api_set_blood_bar_show_type(blood_bar_show_type)
    self.unit.api_set_blood_bar_show_type(blood_bar_show_type)
end

--- 开启残影
---@param r Fixed r
---@param g Fixed g
---@param b Fixed b
---@param a Fixed a
---@param interval Fixed interval
---@param duration Fixed duration
---@param start Fixed start
---@param endd Fixed end
---@param use_raw_texture Bool Use origin texture
function GT.unit:api_start_ghost(r, g, b, a, interval, duration, start, endd, use_raw_texture)
    self.unit.api_start_ghost(r, g, b, a, interval, duration, start, endd, use_raw_texture)
end

--- 关闭残影
function GT.unit:api_stop_ghost()
    self.unit.api_stop_ghost()
end

--- 开始溶解效果
---@param dissolve_time Fixed 溶解时间
---@param sink_dis Fixed 下沉距离
function GT.unit:api_start_dissolve(dissolve_time, sink_dis)
    self.unit.api_start_dissolve(dissolve_time, sink_dis)
end

--- 关闭溶解效果
function GT.unit:api_stop_dissolve()
    self.unit.api_stop_dissolve()
end

--- 设置残影颜色
---@param r Fixed r
---@param g Fixed g
---@param b Fixed b
---@param a Fixed a
function GT.unit:api_set_ghost_color(r, g, b, a)
    self.unit.api_set_ghost_color(r, g, b, a)
end

--- 设置残影时间
---@param interval Fixed interval
---@param duration Fixed duration
---@param start Fixed start
---@param endd Fixed end
function GT.unit:api_set_ghost_time(interval, duration, start, endd)
    self.unit.api_set_ghost_time(interval, duration, start, endd)
end

--- 对单位所属玩家关系播放音乐
---@param camp_target RoleRelation 玩家关系
---@param sid AudioKey 乐曲编号
---@param loop Bool 是否循环
function GT.unit:api_play_sound_by_unit_for_role_relation(camp_target, sid, loop)
    self.unit.api_play_sound_by_unit_for_role_relation(camp_target, sid, loop)
end

--- 设置XRay是否开启
---@param value Bool 布尔值
function GT.unit:api_set_Xray_is_open(value)
    self.unit.api_set_Xray_is_open(value)
end

--- 设置单位隐身被探测到时是否半透明
---@param value Bool 布尔值
function GT.unit:api_set_transparent_when_invisible(value)
    self.unit.api_set_transparent_when_invisible(value)
end

--- 设置单位小地图头像
---@param icon Texture 图片
function GT.unit:api_set_mini_map_icon(icon)
    self.unit.api_set_mini_map_icon(icon)
end

--- 设置敌方单位小地图头像
---@param icon Texture 图片
function GT.unit:api_set_enemy_mini_map_icon(icon)
    self.unit.api_set_enemy_mini_map_icon(icon)
end

--- 单位添加指定编号的效果
---@param modifier_key ModifierKey 效果编号
---@param from_unit GT.unit 来源单位对象
---@param from_ability GT.ability 关联技能
---@param time Fixed 持续时间
---@param cycle_time Fixed 循环周期
---@param stack_count Int32 效果层数
function GT.unit:api_add_modifier(modifier_key, from_unit, from_ability, time, cycle_time, stack_count)
    local a = nil
    if from_ability ~= nil then
        a = from_ability.ability
    end
    self.unit.api_add_modifier(modifier_key, from_unit.unit, a, Fix32(time), Fix32(cycle_time),
        stack_count)
end

--- 获取单位身上指定编号的的效果层数
---@param modifier_key ModifierKey 效果编号
---@return Int32
function GT.unit:api_get_modifier_stack_count(modifier_key)
    return self.unit.api_get_modifier_stack_count(modifier_key)
end

--- 单位身上是否拥有指定编号的效果
---@param modifier_key ModifierKey 效果编号
---@return Bool
function GT.unit:api_has_modifier(modifier_key)
    return self.unit.api_has_modifier(modifier_key)
end

--- 单位身上是否拥有指定标签的效果
---@param tag Str 标签
---@return Bool
function GT.unit:api_has_modifier_with_tag(tag)
    return self.unit.api_has_modifier_with_tag(tag)
end

--- 获取单位身上指定编号的第i个效果实例
---@param add_index Int32 效果位置
---@param modifier_key ModifierKey 效果编号
function GT.unit:api_get_modifier(add_index, modifier_key)
    self.unit.api_get_modifier(add_index, modifier_key)
end

--- 获取单位身上指定编号的第i个效果的个数
---@param modifier_key ModifierKey 效果编号
function GT.unit:api_get_modifier_count(modifier_key)
    self.unit.api_get_modifier_count(modifier_key)
end

--- 移除目标单位身上的目标modifier实例
---@param tar_modifier ModifierEntity 效果编号
function GT.unit:api_remove_modifier_instance(tar_modifier)
    self.unit.api_remove_modifier_instance(tar_modifier)
end

--- 移除目标单位身上的目标modifier类型的所有实例
---@param modifier_key ModifierKey 效果编号
function GT.unit:api_remove_modifier_type(modifier_key)
    self.unit.api_remove_modifier_type(modifier_key)
end

--- 单位身上是否拥有指定类别的效果
---@param modifier_effect_type ModifierEffectType 魔法效果类型
---@return Bool
function GT.unit:api_has_modifier_type(modifier_effect_type)
    return self.unit.api_has_modifier_type(modifier_effect_type)
end

--- 删除单位指定影响类型的魔法效果
---@param effect_type ModifierEffectType 效果影响类型
function GT.unit:api_delete_all_modifiers_by_effect_type(effect_type)
    self.unit.api_delete_all_modifiers_by_effect_type(effect_type)
end

--- 获取单位身上所有的魔法效果
---@return ModifierEntity
function GT.unit:api_get_all_modifiers()
    return self.unit.api_get_all_modifiers()
end

--- 更具单位分类 添加技能
---@param ability_id AbilityKey 技能编号
---@param ability_index AbilityIndex 技能槽位编号
---@param ability_level Int32 技能等级
---@return Ability
function GT.unit:api_add_ability(ability_id, ability_index, ability_level)
    if self:get_type() == UnitCategory['英雄'] then
        self:add_ability(AbilityType['Hero'], ability_id, ability_index, ability_level)
    else
        self:add_ability(AbilityType['Common'], ability_id, ability_index, ability_level)
    end
end

--- 单位添加技能
---@param ability_type AbilityType 技能类型
---@param ability_id AbilityKey 技能编号
---@param ability_index AbilityIndex 技能槽位编号
---@param ability_level Int32 技能等级
function GT.unit:add_ability(ability_type, ability_id, ability_index, ability_level)
    self.unit.api_add_ability(ability_type, ability_id, ability_index, ability_level)
end

---添加技能 自动判断空槽位
---@param ability_id any
function GT.unit:add_ability_index(ability_id)
    local type = AbilityType['Common']
    if self:get_type() == UnitCategory['英雄'] then
        type = AbilityType['Hero']
    end

    for i = 1, 16, 1 do
        local sk = self:api_get_ability(type, i)
        if sk == nil then
            self:add_ability(type, ability_id, i, 1)
            break
        end
    end
end

--- 单位根据槽位移除技能
---@param ability_type Int32 技能类型
---@param ability_index Int32 技能槽位
function GT.unit:api_remove_ability_by_index(ability_type, ability_index)
    self.unit.api_remove_ability_by_index(ability_type, ability_index)
end

--- 单位移除某种类型里所有是指定技能ID的技能
---@param ability_type Int32 技能类型
---@param ability_id AbilityKey 技能ID
function GT.unit:api_remove_abilities_in_type(ability_type, ability_id)
    self.unit.api_remove_abilities_in_type(ability_type, ability_id)
end

--- 单位设置技能等级。
---@param modify Int32 修改方式
---@param ability_type AbilityType 技能类型
---@param ability_index AbilityIndex 技能槽位
---@param level Int32 技能等级
function GT.unit:api_set_ability_level(modify, ability_type, ability_index, level)
    self.unit.api_set_ability_level(modify, ability_type, ability_index, level)
end

--- 单位学习技能
---@param ability_key AbilityKey 技能类型
function GT.unit:api_unit_learn_ability(ability_key)
    self.unit.api_unit_learn_ability(ability_key)
end

--- 获取英雄的技能点
---@return Int32
function GT.unit:api_get_ability_point()
    return self.unit.api_get_ability_point()
end

--- 设置英雄的技能点
---@param ability_point Int32 技能点
function GT.unit:api_set_ability_point(ability_point)
    self.unit.api_set_ability_point(ability_point)
end

--- 增加英雄的技能点
---@param value Int32 技能点
function GT.unit:api_add_ability_point(value)
    self.unit.api_add_ability_point(value)
end

--- 通过技能槽位获取技能
---@param ability_type AbilityType 技能类型
---@param ability_index AbilityIndex 技能槽位
---@return GT.ability
function GT.unit:api_get_ability(ability_index)
    local type = AbilityType['Common']
    if self:get_type() == UnitCategory['英雄'] then
        type = AbilityType['Hero']
    end
    return GT.ability.obj(self.unit.api_get_ability(type, ability_index))
end

--- 通过技能类型加技能ID获取技能
---@param ability_id AbilityKey 技能编号
---@return GT.ability
function GT.unit:api_get_ability_by_type(ability_id)
    local type = AbilityType['Common']
    if self:get_type() == UnitCategory['英雄'] then
        type = AbilityType['Hero']
    end
    return GT.ability.obj(self.unit.api_get_ability_by_type(type, ability_id))
end

--- 获取某种类型的技能列表
---@param ability_type AbilityType 技能类型
---@return Ability
function GT.unit:api_get_abilities_by_type(ability_type)
    return self.unit.api_get_abilities_by_type(ability_type)
end

--- 是否有对应技能类型的技能
---@param ability_id AbilityKey 技能类型
---@return Bool
function GT.unit:api_check_has_ability_type(ability_id)
    return self.unit.api_check_has_ability_type(ability_id)
end

--- 获取单位技能列表
---@return Ability
function GT.unit:get_all_abilities()
    return self.unit.api_get_all_abilities_can_show()
end

--- 交换技能
---@param ability_1 Ability 技能
---@param ability_2 Ability 技能
function GT.unit:api_switch_ability(ability_1, ability_2)
    self.unit.api_switch_ability(ability_1, ability_2)
end

--- 单位禁用技能。
---@param ability_type AbilityType 技能类型
---@param ability_index AbilityIndex 技能槽位
function GT.unit:api_disable_ability(ability_type, ability_index)
    self.unit.api_disable_ability(ability_type, ability_index)
end

--- 单位解禁技能。
---@param ability_type AbilityType 技能类型
---@param ability_index AbilityIndex 技能槽位
function GT.unit:api_enable_ability(ability_type, ability_index)
    self.unit.api_enable_ability(ability_type, ability_index)
end

--- 返回单位实体指定槽位技能的字符串属性值
---@param ability_type AbilityType 技能类型
---@param ability_index AbilityIndex 技能槽位
---@param prop Str 属性名
---@return Str
function GT.unit:api_get_ability_str_attr_value(ability_type, ability_index, prop)
    return self.unit.api_get_ability_str_attr_value(ability_type, ability_index, prop)
end

--- 根据技能序号获取技能对象
---@param seq AbilitySeq 技能序号
---@return Ability
function GT.unit:api_get_ability_by_seq(seq)
    return self.unit.api_get_ability_by_seq(seq)
end

---@class state_id
state_id = {
    ['禁止普工'] = 2,
    ['禁止施法'] = 4,
    ['禁止移动'] = 8,
    ['禁止转向'] = 16,
    ['动画定帧'] = 32,
    ['无法施加运动'] = 64,
    ['无法被技能指示器锁定'] = 128,
    ['隐身'] = 512,
    ['无视静态碰撞'] = 1024,
    ['无视动态碰撞'] = 2048,
    ['无敌'] = 8192,
    ['无法控制'] = 16384,
    ['无法被攻击'] = 32768,
    ['AI无视'] = 65536,
    ['物理伤害免疫'] = 131072,
    ['魔法伤害免疫'] = 262144,
    ['负面魔法效果免疫'] = 524288,
    ['隐藏'] = 1048576,
    ['无法被筛选器选中'] = 2097152,
}

--- 给单位施加状态
---@param state_id state_id 状态ID
function GT.unit:api_add_state(state_id)
    self.unit.api_add_state(state_id)
end

--- 给单位去除状态
---@param state_id state_id 状态ID
function GT.unit:api_remove_state(state_id)
    self.unit.api_remove_state(state_id)
end

--- 是否在战斗状态
---@return Bool
function GT.unit:api_is_in_battle_state()
    return self.unit.api_is_in_battle_state()
end

--- 单位是否处于某状态
---@param state_bit Int32 状态
---@return Bool
function GT.unit:api_has_state(state_bit)
    return self.unit.api_has_state(state_bit)
end

--- 单位施放技能
---@param ability_type Int32 技能类型
---@param ability_index Int32 技能槽位
function GT.unit:api_release_ability_by_index(ability_type, ability_index)
    self.unit.api_release_ability_by_index(ability_type, ability_index)
end

--- 单位施放技能，具有释放目标地点
---@param ability_type Int32 技能类型
---@param ability_index Int32 技能坑位
---@param postion Point 技能目标位置
function GT.unit:api_release_ability_at_position(ability_type, ability_index, postion)
    self.unit.api_release_ability_at_position(ability_type, ability_index, postion)
end

--- 发布建造命令(目标点)
---@param build_key UnitKey 建筑类型
---@param point Point 目标位置
function GT.unit:api_create_building_on_point(build_key, point)
    self.unit.api_create_building_on_point(build_key, point)
end

--- 发布建造命令(坐标)
---@param build_key UnitKey 建筑类型
---@param pos_x Fixed 坐标X
---@param pos_z Fixed 坐标Z
function GT.unit:api_create_building_on_position(build_key, pos_x, pos_z)
    self.unit.api_create_building_on_position(build_key, pos_x, pos_z)
end

--- 单位是否拥有物品
---@param item Item 物品
---@return Bool
function GT.unit:api_has_item(item)
    return self.unit.api_has_item(item)
end

--- 单位是否拥有特定编号物品
---@param item_no ItemKey 物品编号
---@return Bool
function GT.unit:api_has_item_key(item_no)
    return self.unit.api_has_item_key(item_no)
end

--- 给单位添加物品名
---@param item_no ItemKey 物品编号
---@return Item
function GT.unit:api_add_item(item_no)
    return self.unit.api_add_item(item_no)
end

--- 给单位删除物品名
---@param item_key ItemKey 物品编号
---@param num Int32 数量
function GT.unit:api_delete_item(item_key, num)
    self.unit.api_delete_item(item_key, num)
end

--- 单位丢弃物品实体到场景中
---@param item Item 物品
---@param pos FPoint 点
---@param stack_cnt Int32 数量
function GT.unit:api_drop_item(item, pos, stack_cnt)
    self.unit.api_drop_item(item, pos, stack_cnt)
end

--- 单位删除物品实体
---@param stack_cnt Int32 数量
---@param item Item 物品
function GT.unit:api_remove_item(stack_cnt, item)
    self.unit.api_remove_item(stack_cnt, item)
end

--- 获取单位背包槽位的物品
---@param slot_type SlotType 背包槽位
---@param slot_idx Int32 格子下标 从1 开始
---@return  GT.item
function GT.unit:api_get_item_by_slot(slot_type, slot_idx)
    return GT.item.obj(self.unit.api_get_item_by_slot(slot_type, slot_idx))
end

--- 移动物品
---@param item Item 物品
---@param slot_type SlotType 背包槽位
---@param slot_idx UInt32 格子下标
function GT.unit:api_shift_item(item, slot_type, slot_idx)
    self.unit.api_shift_item(item, slot_type, slot_idx)
end

--- 移动物品
---@param item Item 物品
---@param slot_type SlotType 背包槽位
---@param slot_idx UInt32 格子下标
---@param is_force_shift Bool 格子被占是否转移
function GT.unit:api_shift_item_new(item, slot_type, slot_idx, is_force_shift)
    self.unit.api_shift_item_new(item, slot_type, slot_idx, is_force_shift)
end

--- 单位身上所有物品
---@return ItemGroup
function GT.unit:api_get_all_item_pids()
    return self.unit.api_get_all_item_pids()
end

--- 设置单位物品栏的格子数量
---@param cnt UInt64 个数
function GT.unit:api_set_unit_bar_cnt(cnt)
    self.unit.api_set_unit_bar_cnt(cnt)
end

--- 设置单位背包栏的格子数量
---@param cnt UInt64 个数
function GT.unit:api_set_unit_pkg_cnt(cnt)
    self.unit.api_set_unit_pkg_cnt(cnt)
end

--- 单位身上拥有指定类型的物品数量
---@param item_type ItemKey 物品编号
---@return UInt64
function GT.unit:api_get_num_of_item_type(item_type)
    return self.unit.api_get_num_of_item_type(item_type)
end

--- 单位是否商店
---@return Bool
function GT.unit:api_is_shop()
    return self.unit.api_is_shop()
end

--- 获取商店单位范围
---@return Fixed
function GT.unit:api_get_shop_range()
    return self.unit.api_get_shop_range()
end

--- 添加物品商品到商店
---@param tab_name TabName 页签
---@param item_no ItemKey 道具编号
function GT.unit:api_add_shop_item(tab_name, item_no)
    self.unit.api_add_shop_item(tab_name, item_no)
end

--- 获取商店某页签的商品列表
---@param tab_idx TabIdx 页签id
---@return ItemKey
function GT.unit:api_get_shop_item_list(tab_idx)
    return self.unit.api_get_shop_item_list(tab_idx)
end

--- 获取商店商品的恢复时间
---@param tab_idx TabIdx 页签id
---@param item_no ItemKey 道具编号
function GT.unit:api_get_shop_item_cd(tab_idx, item_no)
    self.unit.api_get_shop_item_cd(tab_idx, item_no)
end

--- 获取商店商品的库存恢复间隔
---@param tab_idx TabIdx 页签id
---@param item_num Int32 第N个道具
function GT.unit:api_get_shop_item_default_cd(tab_idx, item_num)
    self.unit.api_get_shop_item_default_cd(tab_idx, item_num)
end

--- 获取商店商品的剩余恢复时间
---@param tab_idx TabIdx 页签id
---@param item_num Int32 第N个道具
function GT.unit:api_get_shop_item_residual_cd(tab_idx, item_num)
    self.unit.api_get_shop_item_residual_cd(tab_idx, item_num)
end

--- 获取商店页签数量
---@return ItemKey
function GT.unit:api_get_shop_tab_cnt()
    return self.unit.api_get_shop_tab_cnt()
end

--- 获取商店的页签名
---@param tab_idx TabIdx 页签id
---@return Str
function GT.unit:api_get_shop_tab_name(tab_idx)
    return self.unit.api_get_shop_tab_name(tab_idx)
end

--- 获取商店指定页签第N个商品的类型
---@param tab_idx TabIdx 页签id
---@param item_idx Int32 商品编号
---@return ItemKey
function GT.unit:api_get_shop_tab_item_type(tab_idx, item_idx)
    return self.unit.api_get_shop_tab_item_type(tab_idx, item_idx)
end

--- 添加单位商品到商店
---@param tab_name TabName 页签
---@param entity_no UnitKey 单位编号
function GT.unit:api_add_shop_unit(tab_name, entity_no)
    self.unit.api_add_shop_unit(tab_name, entity_no)
end

--- 删除商店物品商品
---@param tab_name TabName 页签
---@param item_no ItemKey 道具编号
function GT.unit:api_remove_shop_item(tab_name, item_no)
    self.unit.api_remove_shop_item(tab_name, item_no)
end

--- 删除商店单位商品
---@param tab_name TabName 页签
---@param entity_no UnitKey 单位编号
function GT.unit:api_remove_shop_unit(tab_name, entity_no)
    self.unit.api_remove_shop_unit(tab_name, entity_no)
end

--- 设置物品商品库存
---@param tab_name TabName 页签
---@param item_no ItemKey 道具编号
---@param cnt UInt32 库存
function GT.unit:api_set_shop_item_stock(tab_name, item_no, cnt)
    self.unit.api_set_shop_item_stock(tab_name, item_no, cnt)
end

--- 设置单位商品库存
---@param tab_name TabName 页签
---@param entity_no UnitKey 单位编号
---@param cnt UInt32 库存
function GT.unit:api_set_shop_unit_stock(tab_name, entity_no, cnt)
    self.unit.api_set_shop_unit_stock(tab_name, entity_no, cnt)
end

--- 设置商店开关
---@param is_shop Bool 开关
function GT.unit:api_set_is_shop(is_shop)
    self.unit.api_set_is_shop(is_shop)
end

--- 单位购买物品
---@param shop_unit Unit 商店
---@param tab_idx TabIdx 页签id
---@param item_no ItemKey 物品编号
function GT.unit:api_buy_item_with_tab_name(shop_unit, tab_idx, item_no)
    self.unit.api_buy_item_with_tab_name(shop_unit, tab_idx, item_no)
end

--- 单位购买单位
---@param shop_unit Unit 商店
---@param tab_name TabName 页签
---@param entity_no UnitKey 单位编号
function GT.unit:api_buy_unit_with_tab_name(shop_unit, tab_name, entity_no)
    self.unit.api_buy_unit_with_tab_name(shop_unit, tab_name, entity_no)
end

--- 单位出售物品
---@param shop_unit Unit 商店
---@param item Item 道具
function GT.unit:api_sell_item(shop_unit, item)
    self.unit.api_sell_item(shop_unit, item)
end

--- 设置商店目标
---@param target_unit Unit 目标
function GT.unit:api_set_shop_target(target_unit)
    self.unit.api_set_shop_target(target_unit)
end

--- 获取单位商店物品商品库存
---@param tab_idx TabIdx 页签id
---@param item_no ItemKey 物品编号
---@return Int32
function GT.unit:api_get_shop_item_stock(tab_idx, item_no)
    return self.unit.api_get_shop_item_stock(tab_idx, item_no)
end

--- 获取单位商店单位商品库存
---@param tab_name TabName 页签
---@param entity_no UnitKey 单位编号
---@return Int32
function GT.unit:api_get_shop_unit_stock(tab_name, entity_no)
    return self.unit.api_get_shop_unit_stock(tab_name, entity_no)
end

--- 获取单位商店单位商品售价
---@param tab_name TabName 页签
---@param entity_no UnitKey 单位编号
---@return Fixed
function GT.unit:api_get_shop_item_price(tab_name, entity_no)
    return self.unit.api_get_shop_item_price(tab_name, entity_no)
end

--- 科技升级
---@param tech_no TechKey 科技编号
function GT.unit:api_upgrade_tech(tech_no)
    self.unit.api_upgrade_tech(tech_no)
end

--- 获取科技列表
---@return TechKey
function GT.unit:api_get_tech_list()
    return self.unit.api_get_tech_list()
end

--- 获取科技列表
---@return TechKey
function GT.unit:api_get_affect_techs()
    return self.unit.api_get_affect_techs()
end

--- 获取科技是否满足前置条件
---@param tech_no TechKey 科技编号
---@return TechKey
function GT.unit:api_check_tech_precondition(tech_no)
    return self.unit.api_check_tech_precondition(tech_no)
end

--- 添加科技
---@param tech_no TechKey 科技编号
function GT.unit:api_add_tech(tech_no)
    self.unit.api_add_tech(tech_no)
end

--- 删除科技
---@param tech_no TechKey 科技编号
function GT.unit:api_remove_tech(tech_no)
    self.unit.api_remove_tech(tech_no)
end

--- 发布命令
---@param command UnitCommand 命令
function GT.unit:api_release_command(command)
    self.unit.api_release_command(command)
end

--- 设置单位默认跳转状态
---@param behavior UnitBehavior 默认跳转状态
function GT.unit:api_set_default_switch_behavior(behavior)
    self.unit.api_set_default_switch_behavior(behavior)
end

--- 获取单位编号
---@return UnitKey
function GT.unit:get_UnitKey()
    return self.unit.api_get_key()
end

--- 获取单位所属阵营id
---@return CampID
function GT.unit:api_get_camp_id()
    return self.unit.api_get_camp_id()
end

--- 获取单位所属玩家ID
---@return RoleID
function GT.unit:api_get_role_id()
    return self.unit.api_get_role_id()
end

--- 获取单位所属玩家
---@return GT.player
function GT.unit:get_player()
    return GT.player.obj(self.unit.api_get_role())
end

--- 获取单位所属阵营
---@return Camp
function GT.unit:api_get_camp()
    return self.unit.api_get_camp()
end

--- 获取单位分类 类型
---@return UnitCategory
function GT.unit:get_type()
    return self.unit.api_get_type()
end

--- 获取单位名称
---@return Str
function GT.unit:get_name()
    return self.unit.api_get_name()
end

---@class txt_enum 跳子枚举
txt_enum = {
    ['物理伤害'] = 'physics',
    ['获得金币'] = 'get_gold',
    ['治疗'] = 'heal',
    ['魔法伤害'] = 'magic',
    ['真实伤害'] = 'real',
}


---@class apply_damage_data 造成伤害参数
---@field target_unit GT.unit 伤害者 or nil
---@field ability GT.ability 来源关联技能 or nil
---@field type DMGType 伤害类型 or 物理
---@field damage number 伤害值
---@field is_bounce boolean 是否跳字 默认 true
---@field is_normal boolean 视为普攻  默认 false
---@field is_critical boolean 必定暴击 默认 flase
---@field is_cant_miss boolean 无视闪避 默认 flase
---@field particle particle 受击特效  默认 100001
---@field socket_name string 挂接点 默认 ''
---@field txt_enum txt_enum 跳字枚举 默认 物理

--- 造成伤害
---@param d apply_damage_data
function GT.unit:apply_damage(d)
    local a = nil
    local tu = nil
    if d.ability ~= nil then
        a = d.ability.ability
    end
    if d.target_unit ~= nil then
        tu = d.target_unit.unit
    end
    game_api.apply_damage(self.unit, a, tu, d.type or DMGType['物理伤害'], d.damage, d.is_bounce or true, nil,
        d.is_normal or false, d.is_critical or false, d.is_cant_miss or false, d.particle or 100001, d.socket_name or '',
        d.txt_enum or '')
end

--- 治疗单位
---@param hp_change Fixed 治疗的数值
---@param jump_word Bool 是否跳字
---@param related_ability Ability 关联技能
---@param source_unit Unit 来源单位
---@param harm_text_enum Str 跳字枚举
function GT.unit:api_heal(hp_change, jump_word, related_ability, source_unit, harm_text_enum)
    self.unit.api_heal(hp_change, jump_word, related_ability, source_unit, harm_text_enum)
end

--- 删除单位运动器
function GT.unit:remove_unit_mover()
    game_api.remove_unit_mover(self.unit)
end

--- 打断单位运动器
function GT.unit:break_unit_mover(unit)
    game_api.break_unit_mover(self.unit)
end

---获取单位建造资源消耗属性
---@param unit_id number 单位类型
---@param player_attr_name string 玩家属性名
---@return number
function GT.unit.get_unit_resource_cost(unit_id, player_attr_name)
    return game_api.get_role_attr_by_unit_type(unit_id, player_attr_name)
end

--- 获取单位icon图标的图片id
---@return Int32
function GT.unit:icon()
    return game_api.get_icon_id_by_unit_type(self:get_UnitKey())
end

--- 返回指定单位类型的名称
---@return Str
function GT.unit:get_unit_name_by_type()
    return game_api.get_unit_name_by_type(self:get_UnitKey())
end

--- 返回指定单位类型的描述
---@return Str
function GT.unit:get_unit_desc_by_type()
    return game_api.get_unit_desc_by_type(self:get_UnitKey())
end

--- 成长属性
---@param entity_no UnitKey 单位编号
---@param attr Str 属性名
---@return Fixed
function GT.unit:api_get_attr_growth(attr)
    return game_api.api_get_attr_growth(self:get_UnitKey(), attr)
end

--- 设置成长属性
---@param entity_no UnitKey 单位编号
---@param attr Str 属性名
---@param value Fixed 属性值
function GT.unit.api_set_attr_growth(entity_no, attr, value)
    game_api.api_set_attr_growth(entity_no, attr, value)
end

--- 获取选择圈缩放
---@return Fixed
function GT.unit:get_select_circle_scale()
    game_api.get_select_circle_scale(self.unit)
end

--- 单位实体是否存在
---@param unit GT.unit 单位实体
---@return Bool
function GT.unit.unit_is_exist(unit)
    return game_api.get_select_circle_scale(unit.unit)
end

--- 最近创建单位实体
---@return GT.unit
function GT.unit.get_last_created_unit()
    ---@type unit_data
    local data = {
        unit = game_api.get_last_created_unit()
    }
    return new(GT.unit, data)
end

--- 通过技能序列号获取技能
---@param ability_seq AbilitySeq 技能序列号
---@return GT.ability
function GT.unit:api_get_ability_by_seq(ability_seq)
    ---@type ability_data
    local data = {
        ability = game_api.api_get_ability_by_seq(self.unit, ability_seq)
    }
    return new(GT.ability, data)
end

--- 通过单位编号+技能序列号获取技能
---@param unit_id UnitID 单位ID
---@param ability_seq AbilitySeq 技能序列号
---@return  GT.ability
function GT.unit.api_get_ability_by_unit_and_seq(unit_id, ability_seq)
    ---@type ability_data
    local data = {
        ability = game_api.api_get_ability_by_unit_and_seq(unit_id, ability_seq)
    }
    return new(GT.ability, data)
end

--- 启动行为树
---@param tree_name Str 行为树名称
---@param tree_args Dict 行为树参数
function GT.unit:assign_behavior_tree(tree_name, tree_args)
    game_api.assign_behavior_tree(self.unit, tree_name, tree_args)
end

--- 停止一棵行为树
---@param tree_name Str 行为树名称
function GT.unit:stop_behavior_tree(tree_name)
    game_api.stop_behavior_tree(self.unit, tree_name)
end

--- 停止所有行为树
function GT.unit:stop_all_behavior_tree(unit)
    game_api.stop_all_behavior_tree(self.unit)
end

--- 运行一次行为树
---@param tree_name Str 行为树名称
---@param tree_args Dict 行为树参数
function GT.unit:run_behavior_tree_once(tree_name, tree_args)
    game_api.stop_all_behavior_tree(self.unit, tree_name, tree_args)
end

--- 判断单位敌对关系
---@param unit2 GT.unit 单位
---@return Bool
function GT.unit:is_enemy(unit2)
    return game_api.is_enemy(self.unit, unit2.unit)
end

--- 判断单位友军关系
---@param unit2 GT.unit 单位
---@return Bool
function GT.unit:is_ally(unit2)
    return game_api.is_enemy(self.unit, unit2.unit)
end

--- 玩家或单位是否拥有单位的可见性
---@param role_or_unit GT.player 玩家
---@param unit GT.unit 单位
---@return Bool
function GT.unit:get_visibility_of_unit(role_or_unit)
    return game_api.get_visibility_of_unit(role_or_unit.player, self.unit)
end

---@generic K
---@generic V
---创建自定义值 取值 直接 对象['K'] 修改为 对象.binding['K']
---@param k K
---@param v V
---@param call kv_call
function GT.unit:set(k, v, call)
    self[k] = v
    if call == nil then
        return
    end
    self.bind:add_({
        key = k,
        func = function(val, old)
            if val == nil then
                return
            end
            self[k] = val
            call(k, val, old)
        end
    })
end

---单位出生
---@param key UnitKey 单位编号
---@param fun UNIT_BORN 回调
function GT.unit.event_create_unit(key, fun)
    GT.event.UNIT_BORN(function(u)
        if u:get_UnitKey() == key then
            fun(u)
        end
    end)
end

---获取单位上的魔法效果
---@param type integer 技能类型
---@return GT.modifier[] 魔法效果表
function GT.unit:get_modifier()
    local modifiers = {}
    local py_list = self:api_get_all_modifiers()
    for i = 0, python_len(py_list) - 1 do
        local lua_modifier = GT.modifier.obj(python_index(py_list, i))
        table.insert(modifiers, lua_modifier)
    end
    return modifiers
end

--- 获得建筑单位当前等级
---@return number
function GT.unit:diy_get_build_lv()
    return self['建筑等级'] or nil
end

--- 设置建筑单位当前等级
function GT.unit:diy_set_build_lv(lv)
    self['建筑等级'] = lv
end

--- 增加建筑单位当前等级
function GT.unit:diy_add_build_lv(add)
    self['建筑等级'] = self['建筑等级'] + add
end

--- 获得建筑单位升级 列表
---@return  table<number,build_lvup_class>
function GT.unit:diy_get_build_lv_up()
    return self['建筑升级'] or nil
end

--- 获得建筑单位绑定技能 key
---@return AbilityKey
function GT.unit:diy_get_build_binding_skill()
    return self['绑定建造技能']
end

--- 添加单位 技能事件 造成伤害
---@param key AbilityKey 技能编号
---@param call UNIT_HURT_OTHER_COMPLETE 事件
function GT.unit:diy_add_all_dag_event_ability(key, call)
    if self['技能事件-造成伤害'] == nil then
        ---@type table<AbilityKey,UNIT_HURT_OTHER_COMPLETE[]>
        self['技能事件-造成伤害'] = OrderedTable()
        self['技能事件-造成伤害'][key] = OrderedTable()
    end
    table.insert(self['技能事件-造成伤害'][key], call)
end

--- 获得 单位 技能事件 造成伤害
---@return table<AbilityKey,UNIT_HURT_OTHER_COMPLETE[]>
function GT.unit:diy_get_all_dag_event_ability()
    return self['技能事件-造成伤害']
end

--- 删除 单位 技能事件 造成伤害
---@param key AbilityKey 技能编号
function GT.unit:diy_del_all_dag_event_ability(key)
    if self['技能事件-造成伤害'] == nil then
        return
    end
    if self['技能事件-造成伤害'][key] == nil then
        return
    end
    self['技能事件-造成伤害'][key] = nil
end

---单位添加属性
---默认为'='号 =号情况下失去技能 魔法效果 等等 属性将不会变化
---@param attr table<uKeyAttr, number>
function GT.unit:diy_add_attr(attr)
    if attr ~= nil then
        for k, v in pairs(attr) do
            self.binding[k] = v
            local key = string.gsub(k, "-", "")
            key = string.gsub(key, "+", "")
            key = string.gsub(key, "=", "")
            if key == uKeyAttr['最大生命值'] then
                self.binding[uKeyAttr['当前生命值']] = self[uKeyAttr['最大生命值']]
            end
            if key == uKeyAttr['最大法力值'] then
                self.binding[uKeyAttr['当前法力值']] = self[uKeyAttr['最大生命值']]
            end
        end
    end
end

---单位减去属性
---默认为'='号 =号情况下失去技能 魔法效果 等等 属性将不会变化
---@param attr table<uKeyAttr, number>
function GT.unit:diy_del_attr(attr)
    if attr ~= nil then
        for k, v in pairs(attr) do
            if string.find(k, '=') ~= nil then
                return
            end
            self.binding[k] = -v
            local key = string.gsub(k, "-", "")
            key = string.gsub(key, "+", "")
            key = string.gsub(key, "=", "")
            if key == uKeyAttr['最大生命值'] then
                self.binding[uKeyAttr['当前生命值']] = self[uKeyAttr['最大生命值']]
            end
            if key == uKeyAttr['最大法力值'] then
                self.binding[uKeyAttr['当前法力值']] = self[uKeyAttr['最大生命值']]
            end
        end
    end
end

---@alias shoot_fly_reach fun(u:GT.unit):void 到达高度
---@alias shoot_fly_fall fun(u:GT.unit):void 落下


---@class shoot_fly_data 击飞参数
---@field time number 持续时间(包含下降时间)
---@field z number 高度
---@field reach shoot_fly_reach 到达高度
---@field fall shoot_fly_fall 落下
---@field sfx shoot_fly_sfx 落地特效编号
---@field vertigo vertigo_data 眩晕参数
---@field su GT.unit 眩晕来源单位


---@class shoot_fly_sfx 击飞特效参数
---@field sfx_id SfxKey 特效编号 必填
---@field scale Float 缩放比例 可选 默认 1
---@field height Float 高度 可选 默认 0

---击飞状态
shoot_fly_stata = {
    [1] = state_id['禁止移动'],
    [2] = state_id['禁止施法'],
    [3] = state_id['禁止普工'],
    [4] = state_id['禁止转向'],
}

---返回单位状态是否全部结束
function GT.unit:state()
    if self['击飞'] then
        return false
    end
    if self['眩晕'] then
        return false
    end
    if self['击退'] then
        return false
    end
    return true
end

---禁止
function GT.unit:ban()
    if self['禁止'] then
        return
    end

    self['禁止'] = true

    for i, v in ipairs(shoot_fly_stata) do
        self:api_add_state(v)
    end
end

---解除禁止
function GT.unit:lifted()
    if self['禁止'] == false then
        return
    end
    if self:state() == false then
        return
    end
    self['禁止'] = false
    for i, v in ipairs(shoot_fly_stata) do
        self:api_remove_state(v)
    end
end

---击飞
---@param d shoot_fly_data
function GT.unit:shoot_fly(d)
    if d == nil then
        return
    end
    if d.sfx == nil then
        d.sfx = {}
    end
    local u = self

    if self['击飞'] == false then
        -- self['击飞'] = true
        u:api_add_modifier(modifier_id['击飞'], u, d.su or nil, d.time, 0, 1)

        u:update_pos()
        u.binding.z = u.z
        self['正在击飞'] = tween.new(d.time / (3 / 2), u.binding, { z = u.z + d.z }, 'outQuart')
        GT.timer.obj({
            count = -1,
            delay = 0.03,
            immediately = true,
            callback = function(data, t)
                if self['正在击飞']:update(0.03) then
                    t:delete()
                    if d.reach ~= nil then
                        d.reach(u)
                    end
                    self['正在击飞'] = tween.new(d.time / (3 / 1), u.binding, { z = 0 }, 'inOutQuad')
                    GT.timer.obj2(0.03, function(data, t)
                        if self['正在击飞']:update(0.03) then
                            self['正在击飞'] = nil


                            if d.fall ~= nil then
                                d.fall(u)
                            end
                            -- self['击飞'] = false

                            t:delete()

                            GT.sfx.create_sfx_on_point({
                                sfx_id = d.sfx.sfx_id or 104281,
                                point = u:api_get_position(),
                                height = d.sfx.height or 0,
                                scale = d.sfx.scale or 1,
                            })
                        end
                    end)
                end
            end
        })
    end

    if d.vertigo ~= nil then
        u:api_add_modifier(modifier_id['眩晕'], u, d.su or nil, d.vertigo.time, 1, 1)
    end
end

---@class vertigo_data 眩晕参数
---@field time number 持续时间
---@field sfx_id SfxKey 特效编号


---眩晕
---@param d vertigo_data
function GT.unit:vertigo(d)
    if d == nil then
        return
    end
    for i, v in ipairs(shoot_fly_stata) do
        self:api_add_state(v)
    end
    if self['眩晕'] == false then
        self['眩晕'] = true
        self['眩晕sfx'] = GT.sfx.create_sfx_on_unit({
            sfx_id = d.sfx_id or 102928,
            unit = self,
            socket = 'head',
        })
        self['眩晕tick'] = tick2.group()

        self['眩晕tick_event'] = self['眩晕tick']:delay(
            function()
                self['眩晕sfx']:delete_sfx(false)

                self['眩晕time']:delete()
                self['眩晕'] = false
            end, d.time)

        self['眩晕time'] = GT.timer.obj({
            count = -1,
            delay = 0.03,
            immediately = true,
            callback = function(data, t)
                self['眩晕tick']:update(0.03)
            end
        })
    else

    end
end

---@class repelled_data 击退
---@field distance number 击退距离
---@field origin GT.unit 原点单位
---@field time number 持续时间

---击退
---@param d repelled_data
function GT.unit:repelled(d)
    if d == nil then
        return
    end
    if self['击退'] then
        return
    end
    -- self['击退'] = true
    self:api_add_modifier(modifier_id['击退'], d.origin, nil, d.time, 0, 1)
    ---104475
    self['击退sfx'] = GT.sfx.create_sfx_on_unit({
        sfx_id = 100601,
        socket = 'origin',
        unit = self,
        angle = self:api_get_face_angle()
    })
    self:update_pos()
    self.binding.x = self.x
    self.binding.y = self.y
    ---角度
    local angle = d.origin:api_get_face_angle()
    ---计算击退后的位置
    local pos = GT.polarProjection(self.x, self.y, d.distance, angle)
    self['正在击退'] = tween.new(d.time, self.binding, { x = pos.x, y = pos.y }, 'outQuart')
    GT.timer.obj2(0, function(data, t)
        if self['正在击退']:update(0.01) then
            t:delete()
            self['正在击退'] = nil
            -- self['击退'] = false
            self['击退sfx']:delete_sfx(true)
            self['击退sfx'] = nil
        end
    end)
end

-- ---@class charge_data 冲锋
-- ---@field distance number 击退距离
-- ---@field origin GT.unit 原点单位
-- ---@field time number 持续时间

-- ---冲锋
-- ---@param d any
-- function GT.unit:charge(d)
--     if d == nil then
--         return
--     end

-- end
